package com.irdstudio.efp.esb.api.rest.nls;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Objects;

import javax.servlet.http.HttpServletRequest;

import com.irdstudio.basic.framework.core.constant.EsbRetCodeStandard;
import com.irdstudio.efp.esb.common.constant.InstitutionEnums;
import com.irdstudio.efp.esb.common.constant.dxm.DxmEnum;
import com.irdstudio.efp.esb.common.constant.loan.PerLoanConstant;
import com.irdstudio.efp.loan.service.facade.AccLoanService;
import com.irdstudio.efp.loan.service.vo.AccLoanVO;
import com.irdstudio.efp.nls.common.constant.PrdInfoEnum;
import com.irdstudio.efp.nls.service.facade.ed.LimitControlsService;
import org.apache.rocketmq.common.message.Message;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.irdstudio.basic.framework.core.constant.BaseConstant;
import com.irdstudio.basic.framework.core.constant.CertTypeConstant;
import com.irdstudio.basic.framework.core.constant.CountryConstant;
import com.irdstudio.basic.framework.core.exception.BizException;
import com.irdstudio.basic.framework.core.exception.ESBException;
import com.irdstudio.basic.framework.core.util.DateTool;
import com.irdstudio.basic.framework.core.util.DateUtility;
import com.irdstudio.basic.framework.core.util.MessageRuleCheckUtil;
import com.irdstudio.basic.framework.core.util.StringUtil;
import com.irdstudio.basic.framework.core.util.TraceUtil;
import com.irdstudio.basic.framework.core.util.ValidationUtils;
import com.irdstudio.efp.basic.framework.mq.client.producer.MQProducerMessageClient;
import com.irdstudio.efp.basic.framework.mq.constant.TagEnums;
import com.irdstudio.efp.basic.framework.mq.constant.TopicEnums;
import com.irdstudio.efp.console.common.ConsoleConstant;
import com.irdstudio.efp.console.service.facade.PrdAdaptedSoltService;
import com.irdstudio.efp.console.service.facade.PrdInfoService;
import com.irdstudio.efp.console.service.facade.PubSysInfoService;
import com.irdstudio.efp.console.service.vo.PrdInfoVO;
import com.irdstudio.efp.cus.service.facade.CusIndivService;
import com.irdstudio.efp.esb.api.bean.nls.ReqLoanAppBean;
import com.irdstudio.efp.esb.api.bean.nls.RespLoanAppBean;
import com.irdstudio.efp.esb.api.common.EsbRespServiceBeanCreator;
import com.irdstudio.efp.esb.api.common.GroupeInterface.bd;
import com.irdstudio.efp.esb.api.common.SDicServerConstant;
import com.irdstudio.efp.esb.api.util.SDicMappingServer;
import com.irdstudio.efp.esb.common.constant.EsbBizEnums;
import com.irdstudio.efp.esb.common.constant.EsbSysHeadEnums;
import com.irdstudio.efp.esb.common.constant.MsLoanConstant;
import com.irdstudio.efp.esb.common.constant.nls.AmortPrdctLoanUsgEnum;
import com.irdstudio.efp.esb.common.constant.nls.NlsBrwUsgEnum;
import com.irdstudio.efp.esb.common.constant.nls.NlsProdCdEnum;
import com.irdstudio.efp.esb.common.constant.nls.RvlvPrdctLoanUsgEnum;
import com.irdstudio.efp.esb.common.server.req.EsbReqServiceBean;
import com.irdstudio.efp.esb.common.server.resp.EsbRespServiceBean;
import com.irdstudio.efp.limit.service.facade.LmtPrdContService;
import com.irdstudio.efp.nls.common.constant.PrdAdaptedSoltEnums;
import com.irdstudio.efp.nls.common.constant.QueueTaskEnums;
import com.irdstudio.efp.nls.service.facade.NlsApplyInfoService;
import com.irdstudio.efp.nls.service.facade.queue.NlsProcessBizService;
import com.irdstudio.efp.nls.service.facade.queue.NlsQueueTaskService;
import com.irdstudio.efp.nls.service.facade.sx.NlsCreditInfoService;
import com.irdstudio.efp.nls.service.vo.NlsApplyInfoVO;
import com.irdstudio.efp.nls.service.vo.queue.NlsProcessBizVO;
import com.irdstudio.efp.nls.service.vo.sx.NlsCreditInfoVO;

/**
 * 服务名称 ：30220001(贷款申请管理)<br>
 * 服务场景名称：01(进件申请) <br>
 * 服务描述：用户向相关银行申请贷款业务的处理 <br>
 * 服务场景描述：用户通过相关平台向网贷系统发送证件类型、贷款金额、天数等相关资料信息，由此发起贷款申请； <br>
 *
 * @author huangwb
 * @version 1.0
 * @since 2019年1月18日 下午7:40:24
 */
@RestController
@RequestMapping("/esb")
public class NlsBDController {
    private static Logger logger = LoggerFactory.getLogger(NlsBDController.class);

    /**
     * 获取ESB请求对象，校验 ESB请求系统头和请求应用头对象
     *
     * @param request 请求对象集合
     * @return
     * @author huangwb
     * @version 1.0
     * @since 2019年1月20日 下午1:28:08
     */
    @ModelAttribute("esbReqServiceBean")
    public EsbReqServiceBean getReqEsbHeadBean(HttpServletRequest request) {
        logger.info("校验 ESB请求系统头和请求应用头对象!");
        EsbReqServiceBean esbReqServiceBean = (EsbReqServiceBean) request.getAttribute("esbReqServiceBean");
        return esbReqServiceBean;
    }

    /**
     * 获取ESB请求对象，校验 ESB请求体对象
     *
     * @param request 请求对象集合
     * @return
     * @author huangwb
     * @version 1.0
     * @since 2019年1月20日 下午1:31:14
     */
    @ModelAttribute("reqLoanAppBean")
    public ReqLoanAppBean getReqEsbBodyBean(HttpServletRequest request) {
        logger.info("校验 ESB请求体对象！");
        String esbReqBody = (String) request.getAttribute("esbReqBody");
        return JSONObject.parseObject(esbReqBody, ReqLoanAppBean.class);
    }

    /**
     * 1.通过切面校验进件申请参数是否正确，如不正确则返回错误信息<br>
     * 2.调用对应的中台服务<br>
     * 3.增加调用队列任务表信息<br>
     * TODO:此处为统一的进件交易，先暂时不按照产品代码进行划分，后续根据差异化需求决定是否拆分；<br>
     * V1.1:huangwb:增加交易码
     *
     * @param esbReqServiceBean ESB请求对象
     * @param br1
     * @param reqLoanAppBean    ESB请求体的对象
     * @param br2
     * @param exception         切面的异常信息
     * @return
     * @throws Exception
     * @author huangwb
     * @date 2019年3月4日 下午2:41:17
     * @version 1.1
     * @since 2019年1月20日 下午2:20:51
     */

    @PostMapping("/SERVICE_30220001_01_05")
    public EsbRespServiceBean doRecv(@Validated @ModelAttribute("esbReqServiceBean") EsbReqServiceBean esbReqServiceBean, BindingResult br1,
                                     @Validated({bd.class}) @ModelAttribute("reqLoanAppBean") ReqLoanAppBean reqLoanAppBean, BindingResult br2, Exception exception)
            throws Exception {

        String applSeq = reqLoanAppBean.getAppFlowNo();
        String glblSrlNo = esbReqServiceBean.getSysHead().getGlblSrlNo();
        TraceUtil.setTraceId(glblSrlNo);
        logger.info("进件申请交易开始----------申请流水号：" + applSeq + "------------全局流水号" + glblSrlNo);
        try {
            // 1.通过切面校验进件申请参数是否正确，如不正确则返回错误信息
            if (Objects.nonNull(exception)) {
                throw exception;
            }
            //需求编号:【额度管控】增加个人综合消费贷款+担保方式-信用类产品判断 2019/10/11 modify by ludayong
            String prdId = limitControlsService.queryPrdIdByLoanCate(PerLoanConstant.PRD_STATUS_2, PerLoanConstant.LOAN_CATE_001, BaseConstant.ASSURE_MEANS_00);
            // 查询用信数据
            NlsApplyInfoVO checkTemmp = new NlsApplyInfoVO();
            checkTemmp.setCertType(reqLoanAppBean.getCertTp());
            checkTemmp.setCertCode(reqLoanAppBean.getCertNo());
            //需求编号:【额度管控】增加个人综合消费贷款+担保方式-信用类产品判断 2019/10/11 modify by ludayong
            checkTemmp.setPrdId(prdId);
            List<NlsApplyInfoVO> nlsApplyInfoVoList = nlsApplyInfoService.queryListByConditions(checkTemmp);
            boolean isFirstApply = true;
                if (nlsApplyInfoVoList != null && nlsApplyInfoVoList.size() > 0) {
                    for (NlsApplyInfoVO tempVO : nlsApplyInfoVoList) {
                        // 不允许同一客户下 多笔待放款用信
                        if (MsLoanConstant.NlsApplyStateEnum.PASS.getVALUE().equals(tempVO.getNlsApplyState()) && BaseConstant.DN_STS_3.equals(tempVO.getDnSts())) {
                            logger.debug("用信申请证件号码：" + "【" + reqLoanAppBean.getCertNo() + "】" + "该用户存在待放款用信！");
                            return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean,
                                    JSON.toJSONString(buildRespLoanAppBean(EsbBizEnums.RetCodeEnum.YWLJCLYC.getVALUE(),
                                            "用信申请证件号码：" + "【" + reqLoanAppBean.getCertNo() + "】" + "，该用户存在待放款用信！")),
                                    EsbSysHeadEnums.RetStEnum.FAILURE.getCode(),
                                    EsbBizEnums.RetCodeEnum.YWLJCLYC.getVALUE(),
                                    "用信申请证件号码：" + "【" + reqLoanAppBean.getCertNo() + "】" + ",该用户存在待放款用信");
                        }
                        // 用信存在在途操作（百度、马上一并判断）根据身份证 客户号查询 用客户的证件类型 证件号码搜索审批中的贷款申请(产品范围：网贷系统内产品)，如存在则拒绝新的申请
                        if (MsLoanConstant.NlsApplyStateEnum.APPR.getVALUE().equals(tempVO.getNlsApplyState()) || MsLoanConstant.NlsApplyStateEnum.HANG.getVALUE().equals(tempVO.getNlsApplyState())) {
                            logger.debug("用信申请证件号码：" + "【" + reqLoanAppBean.getCertNo() + "】" + "已经存在处理中用信申请！");
                            return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean, //
                                    JSON.toJSONString(buildRespLoanAppBean(EsbBizEnums.RetCodeEnum.YWLJCLYC.getVALUE(),
                                            "用信申请证件号码：" + "【" + reqLoanAppBean.getCertNo() + "】" + "，已经存在处理中用信申请，请核查！")), //
                                    EsbSysHeadEnums.RetStEnum.FAILURE.getCode(), //
                                    EsbBizEnums.RetCodeEnum.YWLJCLYC.getVALUE(), //
                                    "用信申请证件号码：" + "【" + reqLoanAppBean.getCertNo() + "】" + "，已经存在处理中用信申请，请核查！");
                        }
                        // 字段校验开始： 设置非首次用信标记
                        if (MsLoanConstant.NlsApplyStateEnum.PASS.getVALUE().equals(tempVO.getNlsApplyState())){
                            isFirstApply = false;
                        }
                    }
                }
             // 针对百度尊享贷以及满意贷处理的字段校验
            this.checkFieldMsg(isFirstApply,reqLoanAppBean);

            // 2.获取业务逻辑字段
            String cusName = reqLoanAppBean.getBrwNm();
            String certType = StringUtil.isNullorBank(reqLoanAppBean.getCertTp()) ? CertTypeConstant.CODE_10100 : SDicMappingServer.getLocalSysDicVal(SDicServerConstant.CERT_TYPE, reqLoanAppBean.getCertTp());
            String certNo = reqLoanAppBean.getCertNo();
            String mobile = reqLoanAppBean.getMblNo();
            String prdCde = reqLoanAppBean.getProdCd();
            String bankCardNo = reqLoanAppBean.getBankCardNo();
            BigDecimal loanAmt = new BigDecimal(reqLoanAppBean.getLoanAmt() == null ? "0" : reqLoanAppBean.getLoanAmt());
            String chanFlg = reqLoanAppBean.getChanFlg();
            String bdReqSn = reqLoanAppBean.getRepeatRqsBss();
            String crdtTrm = reqLoanAppBean.getCrdtTrm();
            long txnTmstmp = Long.parseLong(reqLoanAppBean.getTxnTmstmp());
            String aplDt = DateTool.formateDate(new Date(txnTmstmp), DateTool.PATTERN_DEFAULT);

            NlsApplyInfoVO nlsApplyInfoVO = new NlsApplyInfoVO();
            nlsApplyInfoVO.setApplySeq(applSeq);
            nlsApplyInfoVO.setBdReqSn(bdReqSn);
            //根据流水号以及百度reqSn判断，流水号是数据表主键，不重复，reqSn是百度保持不重复
            nlsApplyInfoVO = nlsApplyInfoService.queryCopy(nlsApplyInfoVO);
            if (nlsApplyInfoVO != null) {
                return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean, //
                        JSON.toJSONString(buildRespLoanAppBean(EsbBizEnums.RetCodeEnum.YWLJCLYC.getVALUE(),
                                "用信申请流水号：" + "【" + applSeq + "】" + "，已经存在用信申请记录，请核查！")), //
                        EsbSysHeadEnums.RetStEnum.FAILURE.getCode(), //
                        EsbBizEnums.RetCodeEnum.YWLJCLYC.getVALUE(), //
                        "用信申请流水号：" + "【" + applSeq + "】" + "，已经存在用信申请记录，请核查！");
            }

            NlsCreditInfoVO nlsCreditInfoVO = new NlsCreditInfoVO();
            nlsCreditInfoVO.setBdTransactionId(StringUtil.replaceNullByObj(reqLoanAppBean.getEvID()));
            nlsCreditInfoVO = nlsCreditInfoService.queryByPk(nlsCreditInfoVO);
            String crdtAppFlowNo = "";
            if (nlsCreditInfoVO != null && !StringUtil.isNullorBank(nlsCreditInfoVO.getLmtApplySeq())) {
                crdtAppFlowNo = nlsCreditInfoVO.getLmtApplySeq();
            }
          /*      // 存量数据去掉校验
                if(!nlsCreditInfoVO.getPrdCode().equals(prdCde)) {
                    throw new BizException("用信与授信产品不一致");
                }

                // 3.1.字段值合规性校验
                if(StringUtil.isNullorBank(crdtAppFlowNo)) {
                    throw new BizException("授信流水号不能为空");
                }*/
            //判断该进件贷款用途是否为"消费"
            if (NlsProdCdEnum.MYD.getValue().equals(prdCde)) {
                if (!RvlvPrdctLoanUsgEnum.GRRCXF.getValue().equals(reqLoanAppBean.getRvlvPrdctLoanUsg()) &&
                        !RvlvPrdctLoanUsgEnum.QTXF.getValue().equals(reqLoanAppBean.getRvlvPrdctLoanUsg())) {
                    throw new BizException("贷款用途不为“消费”");
                }
                if (Integer.valueOf(reqLoanAppBean.getCrdtTrm())< 3 || Integer.valueOf(reqLoanAppBean.getCrdtTrm())> 12) {// 贷款期限判断
                    logger.debug("满意贷用信申请贷款期限错误**************");
                    throw new BizException("百度用信申请贷款期限错误");
                }

            } else if (NlsProdCdEnum.ZXD.getValue().equals(prdCde)) {
                if (!AmortPrdctLoanUsgEnum.GRXF.getValue().equals(reqLoanAppBean.getAmortPrdctLoanUsg()) &&
                        !AmortPrdctLoanUsgEnum.QTXF.getValue().equals(reqLoanAppBean.getAmortPrdctLoanUsg())) {
                    throw new BizException("贷款用途不为“消费”");
                }

                if (Integer.valueOf(reqLoanAppBean.getCrdtTrm())< 3 || Integer.valueOf(reqLoanAppBean.getCrdtTrm())>36)
                {
                    logger.debug("尊享贷用信申请贷款期限错误**************");
                    throw new BizException("百度用信申请贷款期限错误");
                }

                AccLoanVO av = new AccLoanVO();
                av.setBillNo(applSeq);
                av = accLoanService.queryByPk(av);
                if (av != null) {
                    // 0 出帐未确认 1 正常 10 逾期 11 理赔结清 2 冲正  3 结清 4 失败 5 销户 6 垫款 7 已扣款  8 置换 9 核销  12 撤销
                    if (BaseConstant.STD_ZB_ACC_STATUS_1.equals(av.getAccountStatus()) || "10".equals(av.getAccountStatus()) || "0".equals(av.getAccountStatus())) {
                        logger.debug("尊享贷用信申请:该用户存在未结清借据信息**************");
                        throw new BizException("该用户存在尊享贷未结清借据信息");
                    }
                }
            }

            //授信有效期校验
//			LmtPrdContVO lmtPrdContVO = new LmtPrdContVO();
//			lmtPrdContVO.setLmtApplySeq(crdtAppFlowNo);
//			lmtPrdContVO.setLmtStatus(ConsoleConstant.LIMIT_STS_02);
//			lmtPrdContVO = lmtPrdContService.queryByPk(lmtPrdContVO);
//			if (lmtPrdContVO == null || "".equals(lmtPrdContVO.getValidDays()) || "".equals(lmtPrdContVO.getExpireDate())) {
//				throw new BizException("无额度有效期");
//			}
//			String expireDate = lmtPrdContVO.getValidDays(); //授信有效期
//			if(0 < DateUtility.compareToDate(new SimpleDateFormat("yyyy-MM-dd").format(new Date()),expireDate)) {
//				//更新额度状态为失效
//				lmtPrdContVO.setLmtStatus(ConsoleConstant.LIMIT_STS_03);
//				lmtPrdContService.updateByPk(lmtPrdContVO);
//				throw new BizException("该笔授信额度已经过期");
//			}

            MessageRuleCheckUtil.validateIdNo18(certNo);// 身份证
            boolean flag = ValidationUtils.validPhoneNum("0", mobile);// 手机号
            if (flag == false) {
                throw new BizException("手机号错误");
            }
            // 根据身份证获取客户号
            String cusId = cusIndivService.getCusIdByCertCode(certType, certNo);
            cusId = StringUtil.isNullorBank(cusId) ? "" : cusId;
            // 根据产品代码查询产品id
            PrdInfoVO vo = new PrdInfoVO();
            vo.setPrdCode(prdCde);
            PrdInfoVO outputVo = prdInfoService.queryLastPrdInfo(vo);
            if (outputVo == null || "".equals(outputVo.getPrdId())) {
                throw new BizException("无产品id");
            }
            BigDecimal maxAmt = outputVo.getLoanAppMaxAmt();
            BigDecimal minAmt = outputVo.getLoanAppMinAmt();
            // 产品最大支用金额
            if (loanAmt.compareTo(maxAmt) == 1) {
                throw new BizException("用信申请金额：" + "【" + loanAmt + "】" + "大于产品最大支用额度：" + "【" + maxAmt + "】");
            }
            // 产品最小支用金额
            if (loanAmt.compareTo(minAmt) == -1) {
                throw new BizException("用信申请金额：" + "【" + loanAmt + "】" + "小于产品最小支用额度：" + "【" + minAmt + "】");
            }

            // 4.调用中台服务
            // 插入网贷申请基本信息表
            nlsApplyInfoVO = new NlsApplyInfoVO();
            nlsApplyInfoVO.setApplySeq(applSeq);// 流水号
            nlsApplyInfoVO.setCusId(cusId);// 客户id
            nlsApplyInfoVO.setCusName(cusName);// 姓名
            nlsApplyInfoVO.setCertType(certType);// 证件类型
            nlsApplyInfoVO.setCertCode(certNo);// 证件号码
            nlsApplyInfoVO.setMobile(mobile);// 手机号码
            nlsApplyInfoVO.setPrdId(outputVo.getPrdId());// 产品id
            nlsApplyInfoVO.setPrdCode(prdCde);// 产品代码
            nlsApplyInfoVO.setPrdName(outputVo.getPrdName());// 产品名称
            nlsApplyInfoVO.setCusNational(reqLoanAppBean.getNation() == null ? CountryConstant.CHN
                    : SDicMappingServer.getLocalSysDicVal(SDicServerConstant.COUNTRY, reqLoanAppBean.getNation()));// 国籍
            nlsApplyInfoVO.setApplyAmt(loanAmt);// 贷款金额
            nlsApplyInfoVO.setLoanPurpose(NlsBrwUsgEnum.CONSUME.getValue());//贷款用途，消费
            nlsApplyInfoVO.setRecvAcctNo(bankCardNo);// 银行卡号
            nlsApplyInfoVO.setApplyDate(aplDt);//申请日期
            // TODO
            nlsApplyInfoVO.setApplyTime(DateUtility.getCurrAppTimeStr());// 申请时间（当前机器时间）
            nlsApplyInfoVO.setCreateUser("admin");// 创建人（直接插值）
            nlsApplyInfoVO.setCreateTime(DateUtility.getCurrAppDateTimeString());// 创建时间
            nlsApplyInfoVO.setLastModifyUser("admin");// 最后修改人（ 直接插值）
            nlsApplyInfoVO.setLastModifyTime(DateUtility.getCurrAppDateTimeString());// 最后修改时间
            nlsApplyInfoVO.setLoanCcy("CNY");// 贷款币种
            nlsApplyInfoVO.setNlsApplyState(MsLoanConstant.NlsApplyStateEnum.APPR.VALUE);// 处理中
            // TODO
            // nlsApplyInfoVO.setChannelNo(outputVo.getPrdType());// 渠道编号
            if (NlsProdCdEnum.MYD.getValue().equals(prdCde)) {// 还款方式
                nlsApplyInfoVO.setRepayMethod(ConsoleConstant.REPAY_MODE_201);
            } else if (NlsProdCdEnum.ZXD.getValue().equals(prdCde)) {
                nlsApplyInfoVO.setRepayMethod(ConsoleConstant.REPAY_MODE_102);
            }
            nlsApplyInfoVO.setGlobalSerno(esbReqServiceBean.getSysHead().getGlblSrlNo());// 全局流水号
            nlsApplyInfoVO.setPlatfmId(
                    "".equals(esbReqServiceBean.getSysHead().getPlafmID()) || esbReqServiceBean.getSysHead().getPlafmID() == null ?
                            MsLoanConstant.PlafmEnum.BD.VALUE : esbReqServiceBean.getSysHead().getPlafmID()
            );// 平台ID
            nlsApplyInfoVO.setPlatfmUsrID(
                    "".equals(esbReqServiceBean.getSysHead().getPlafmUsrID()) ?
                            chanFlg + certNo : esbReqServiceBean.getSysHead().getPlafmUsrID()
            );// 平台用户ID
            nlsApplyInfoVO.setCnsmrTxnCd(esbReqServiceBean.getSysHead().getCnsmrSysID());// 交易码
            nlsApplyInfoVO.setBdIdpicture0(reqLoanAppBean.getIdentFrtPhtFlCd());//身份证正面照文件编码
            nlsApplyInfoVO.setBdIdpicture1(reqLoanAppBean.getIdentObvrPhtFlCd());//身份证反面照文件编码
            nlsApplyInfoVO.setBdLivingPhoto(reqLoanAppBean.getLivPhtCd());//活体照片编码
            nlsApplyInfoVO.setBdUnionLoanUsed(reqLoanAppBean.getRvlvPrdctLoanUsg());//循环产品贷款用途
            if(!"-9999".equals(reqLoanAppBean.getAmortPrdctLoanUsg())){
                nlsApplyInfoVO.setBdLoanUse(reqLoanAppBean.getAmortPrdctLoanUsg());//分期产品贷款用途
            }

            nlsApplyInfoVO.setBdOcrExpdate(reqLoanAppBean.getOCRIdnfFalDt());//ocr识别失效日期
            nlsApplyInfoVO.setLoanTerm(crdtTrm);//贷款期限
            nlsApplyInfoVO.setBdTerm(crdtTrm);//百度贷款期限
            nlsApplyInfoVO.setLoanTermType(BaseConstant.TERM_TYPE_MONTH);//期限类型
            nlsApplyInfoVO.setBdCompreAnnualInterestRate(reqLoanAppBean.getCmprhYrRate());//综合年化利率
            // TODO

            nlsApplyInfoVO.setBdDailyInterestRate(new BigDecimal(reqLoanAppBean.getDayRate() == null ? "0" : reqLoanAppBean.getDayRate()));//日利率

            nlsApplyInfoVO.setBdDailyPenaltyRate(new BigDecimal(reqLoanAppBean.getDayPnyIntRate() == null ? "0" : reqLoanAppBean.getDayPnyIntRate()));//日罚息
            if(!"-9999".equals(reqLoanAppBean.getElyRpyDfltAmt())){
                nlsApplyInfoVO.setBdViolatePrepay(StringUtil.isEmpty(reqLoanAppBean.getElyRpyDfltAmt())? "0" : reqLoanAppBean.getElyRpyDfltAmt());//提前还款违约金
            }
            if(!"-9999".equals(reqLoanAppBean.getDfltAmtClcRule())){
                nlsApplyInfoVO.setBdViolatePrepayRule(StringUtil.isEmpty(reqLoanAppBean.getDfltAmtClcRule()) ? "" : reqLoanAppBean.getDfltAmtClcRule());//提前还款违约金计算规则
            }
            if(!"-9999".equals(reqLoanAppBean.getYrMoDayFlg())){
                nlsApplyInfoVO.setBdViolatePrepayFlag(reqLoanAppBean.getYrMoDayFlg());//年月日标志
            }
            // nlsApplyInfoVO.setChannelNo(reqLoanAppBean.getChanFlg());//渠道标志
            nlsApplyInfoVO.setLmtApplySeq(crdtAppFlowNo);//授信申请流水号
            nlsApplyInfoVO.setBdIdpictureState(MsLoanConstant.BdIdEnum.WAIT.VALUE);//百度照片处理状态
            nlsApplyInfoVO.setChannelNo(chanFlg);
            nlsApplyInfoVO.setSoltStage(PrdAdaptedSoltEnums.SoltStageEnum.LETTER.getVALUE());//插槽阶段 用信
            nlsApplyInfoVO.setBdReqSn(reqLoanAppBean.getRepeatRqsBss());//重复请求依据
            nlsApplyInfoVO.setBdTransactionId(reqLoanAppBean.getEvID());//事务ID
            nlsApplyInfoVO.setBdReasonCode(StringUtil.replaceNullByObj(reqLoanAppBean.getBDRsnCd()));//百度原因码
            nlsApplyInfoVO.setBdReasonMsg(StringUtil.replaceNullByObj(reqLoanAppBean.getBDRsnCdRmk()));//百度原因码说明
            nlsApplyInfoVO.setBdRisCode(reqLoanAppBean.getBDPolcyCd());//百度策略码
            nlsApplyInfoVO.setBdOrderId(reqLoanAppBean.getBaiduCrWthdrwlId());//百度用信和提款订单ID
            // add by ludayong 2019/11/15 【数据权限】增加网贷经办机构赋值
            // 网贷经办机构
            nlsApplyInfoVO.setNlsOperOrgid(InstitutionEnums.InstitutionEnum.GZYHZHYHZXSCTD1.getCode());
            int num1 = nlsApplyInfoService.insertNlsApplyInfo(nlsApplyInfoVO);

            // 插入网贷业务过程表
            NlsProcessBizVO inNlsProcessBizVo = new NlsProcessBizVO();
            inNlsProcessBizVo.setApplySeq(applSeq);// 申请流水号
            inNlsProcessBizVo.setCusId(cusId);// 客户编号
            inNlsProcessBizVo.setCusName(cusName);// 客户名称
            inNlsProcessBizVo.setPrdId(outputVo.getPrdId());// 产品ID
            inNlsProcessBizVo.setPrdCode(prdCde);// 产品代码
            inNlsProcessBizVo.setPrdName(outputVo.getPrdName());// 产品名称
            inNlsProcessBizVo.setHangTimes(QueueTaskEnums.QueueHangTimesEnum.INITIALIZE.getTimes());
            inNlsProcessBizVo.setQueueTaskState(QueueTaskEnums.QueueTaskStateEnum.EXECUTORY.getCode());
            inNlsProcessBizVo.setCreateTime(DateUtility.getCurrAppDateTimeString());// 创建时间
            inNlsProcessBizVo.setLastModifyTime(DateUtility.getCurrAppDateTimeString());// 最后修改时间
            inNlsProcessBizVo.setCreateDate(DateUtility.getCurrAppDateStr());// 创建日期
            // add by ludayong 2019/11/15 【数据权限】增加经办机构赋值
            // 经办机构
            inNlsProcessBizVo.setNlsOperOrgid(InstitutionEnums.InstitutionEnum.GZYHZHYHZXSCTD1.getCode());
            int num2 = nlsProcessBizService.insertNlsProcessBiz(inNlsProcessBizVo);

            if (num1 == -1 || num2 == -1) {
                throw new BizException("插入数据表异常!");
            } else {
                // 5.组装返回报文
                producerService.sendMsg(new Message(TopicEnums.QUEUE_TASK_TOPIC.getTopicId(), TagEnums.TAG_QUEUE_TASK.getTagId(), applSeq,
                        JSON.toJSONString(nlsApplyInfoVO).getBytes("UTF-8")));
                return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean, //
                        JSON.toJSONString(buildRespLoanAppBean(EsbBizEnums.RetCodeEnum.SUCCESS.getVALUE(), "交易成功")), //
                        EsbSysHeadEnums.RetStEnum.SUCCESS.getCode(), //
                        EsbBizEnums.RetCodeEnum.SUCCESS.getVALUE(), //
                        "交易成功");
            }
        } catch (ESBException e) {
            logger.error("申请审批服务接口处理失败!" + e.getMessage());
            e.printStackTrace();
            return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean, //
                    JSON.toJSONString(buildRespLoanAppBean(EsbBizEnums.RetCodeEnum.OTHERS_EXCEPTION.getVALUE(), e.getMessage())), //
                    EsbSysHeadEnums.RetStEnum.FAILURE.getCode(), //
                    EsbBizEnums.RetCodeEnum.OTHERS_EXCEPTION.getVALUE(), //
                    e.getMessage());
        } catch (BizException e) {
            logger.error("申请审批服务接口处理失败!" + e.getMessage());
            e.printStackTrace();
            return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean, //
                    JSON.toJSONString(buildRespLoanAppBean(EsbBizEnums.RetCodeEnum.OTHERS_EXCEPTION.getVALUE(), e.getMessage())), //
                    EsbSysHeadEnums.RetStEnum.FAILURE.getCode(), //
                    EsbBizEnums.RetCodeEnum.OTHERS_EXCEPTION.getVALUE(), //
                    e.getMessage());
        } catch (Exception e) {
            logger.error("申请审批服务接口处理失败!" + e.getMessage());
            e.printStackTrace();
            return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean, //
                    JSON.toJSONString(buildRespLoanAppBean(EsbBizEnums.RetCodeEnum.OTHERS_EXCEPTION.getVALUE(), e.getMessage())), //
                    EsbSysHeadEnums.RetStEnum.FAILURE.getCode(), //
                    EsbBizEnums.RetCodeEnum.OTHERS_EXCEPTION.getVALUE(), //
                    e.getMessage());
        } finally {
            logger.info("进件申请交易结束----------申请流水号：" + applSeq + "------------全局流水号" + glblSrlNo);
            TraceUtil.clear();
        }
    }

    /**
     * 组织用户借款请求接口的返回对象
     *
     * @param retStCd 返回状态码
     * @param rtnMsg  返回信息
     * @return
     * @author huangwb
     * @version 1.0
     * @since 2019年1月20日 下午1:59:46
     */
    private RespLoanAppBean buildRespLoanAppBean(String retStCd, String rtnMsg) {
        RespLoanAppBean respLoanAppBean = new RespLoanAppBean();
        respLoanAppBean.setRetStCd(retStCd);
        respLoanAppBean.setRtnMsg(rtnMsg);
        return respLoanAppBean;
    }


    private void checkFieldMsg(boolean isFirstApply,ReqLoanAppBean reqLoanAppBean) throws Exception{
        String fieldCheckMsg = "";
        if (isFirstApply){
            // 身份证正面
            if(!StringUtil.isNotEmpty(reqLoanAppBean.getIdentFrtPhtFlCd())){
                fieldCheckMsg = "身份证照片正面IdentFrtPhtFlCd";
            }
            // 身份证反面
            if(!StringUtil.isNotEmpty(reqLoanAppBean.getIdentObvrPhtFlCd())){
                fieldCheckMsg = fieldCheckMsg +"身份证照片反面IdentObvrPhtFlCd";
            }
            //活体照片
            if(!StringUtil.isNotEmpty(reqLoanAppBean.getLivPhtCd())){
                fieldCheckMsg = fieldCheckMsg + "活体照片LivPhtCd";
            }
            if(!StringUtil.isNotEmpty(reqLoanAppBean.getOCRIdnfFalDt())){
                fieldCheckMsg = fieldCheckMsg+"ocr识别失效日期OCRIdnfFalDt";
            }
            // 满易贷首次必输
            if (NlsProdCdEnum.MYD.getValue().equals(reqLoanAppBean.getProdCd())) {
                // 进行首次用信字段校验 首次用信字段去掉切面校验
            }
            // 尊享贷首次必输
            if (NlsProdCdEnum.ZXD.getValue().equals(reqLoanAppBean.getProdCd())) {
                // 进行首次用信字段校验 首次用信字段去掉切面校验
                // 贷款用途
                if(!StringUtil.isNotEmpty(reqLoanAppBean.getAmortPrdctLoanUsg())){
                    fieldCheckMsg = fieldCheckMsg+"分期产品贷款用途AmortPrdctLoanUsg";
                }

            }
            MessageRuleCheckUtil.checkNumeric(reqLoanAppBean.getOCRIdnfFalDt(), "ocr识别失效日期");
        }
        // 满易贷 用信必输
        if (NlsProdCdEnum.MYD.getValue().equals(reqLoanAppBean.getProdCd())) {
            // 贷款用途字段校验
            if(!StringUtil.isNotEmpty(reqLoanAppBean.getRvlvPrdctLoanUsg())) {
                fieldCheckMsg = fieldCheckMsg+"循环产品贷款用途RvlvPrdctLoanUsg";

            }
        }
        // 尊享贷 用信必输
        if (NlsProdCdEnum.ZXD.getValue().equals(reqLoanAppBean.getProdCd())) {
            // 提前还款违约金
            if(!StringUtil.isNotEmpty(reqLoanAppBean.getElyRpyDfltAmt())) {
                fieldCheckMsg = fieldCheckMsg+"提前还款违约金ElyRpyDfltAmt";

            }
            // 提前还款违约金计算规则
            if(!StringUtil.isNotEmpty(reqLoanAppBean.getDfltAmtClcRule())) {
                fieldCheckMsg = fieldCheckMsg+"提前还款违约金计算规则DfltAmtClcRule";

            }
            // 年月日标记
            if(!StringUtil.isNotEmpty(reqLoanAppBean.getYrMoDayFlg())) {
                fieldCheckMsg = fieldCheckMsg+"年月日标志YrMoDayFlg";
            }
        }
        if(StringUtil.isNotEmpty(fieldCheckMsg)){
            fieldCheckMsg = fieldCheckMsg+"  may not to null";
            throw new BizException(fieldCheckMsg);
        }
        MessageRuleCheckUtil.checkDouble(reqLoanAppBean.getLoanAmt(), "贷款金额");
        MessageRuleCheckUtil.checkDouble(reqLoanAppBean.getDayPnyIntRate(), "日罚息");
        MessageRuleCheckUtil.checkDouble(reqLoanAppBean.getDayRate(), "日利率");
        MessageRuleCheckUtil.checkDouble(reqLoanAppBean.getCmprhYrRate(), "综合年化利率");
        MessageRuleCheckUtil.checkInteger(reqLoanAppBean.getCrdtTrm(), "贷款期限");
        MessageRuleCheckUtil.checkNumeric(reqLoanAppBean.getTxnTmstmp(), "交易时间戳");
    }

    @Autowired
    @Qualifier("lmtPrdContService")
    private LmtPrdContService lmtPrdContService;
    @Autowired
    @Qualifier("nlsApplyInfoService")
    private NlsApplyInfoService nlsApplyInfoService;
    @Autowired
    @Qualifier("nlsCreditInfoService")
    private NlsCreditInfoService nlsCreditInfoService;
    @Autowired
    @Qualifier("nlsQueueTaskService")
    private NlsQueueTaskService nlsQueueTaskService;
    @Autowired
    @Qualifier("nlsProcessBizService")
    private NlsProcessBizService nlsProcessBizService;
    @Autowired
    @Qualifier("cusIndivService")
    private CusIndivService cusIndivService;
    @Autowired
    @Qualifier("prdInfoService")
    private PrdInfoService prdInfoService;
    @Autowired
    @Qualifier("prdAdaptedSoltService")
    private PrdAdaptedSoltService prdAdaptedSoltService;
    @Autowired
    @Qualifier("pubSysInfoService")
    private PubSysInfoService pubSysInfoService;
    @Autowired
    @Qualifier("producerService")
    private MQProducerMessageClient producerService;
    @Autowired
    @Qualifier("accLoanService")
    private AccLoanService accLoanService;// 借据信息
    @Autowired
    @Qualifier("limitControlsService")
    private LimitControlsService limitControlsService;// 借据信息
}
